home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1998 February / CD WARE MULTIMEDIA (02-1998) CD++.iso / Encript / SNOW / SOURCE.ZIP / snow / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-11  |  5.0 KB  |  262 lines

  1. /*
  2.  * Command-line program for hiding and extracting messages within
  3.  * the whitespace of text files.
  4.  *
  5.  * Usage: snow [-C][-Q][-S][-p passwd][-l line-len] [-f file | -m message]
  6.  *                    [infile [outfile]]
  7.  *
  8.  *    -C : Use compression
  9.  *    -Q : Be quiet
  10.  *    -S : Calculate the space available in the file
  11.  *    -l : Maximum line length allowanble
  12.  *    -p : Specify the password to encrypt the message
  13.  *
  14.  *    -f : Insert the message contained in the file
  15.  *    -m : Insert the message given
  16.  *
  17.  * If the program is executed without either of the -f or -m options
  18.  * then the program will attempt to extract a concealed message.
  19.  * The output will go to outfile if specified, stdout otherwise.
  20.  *
  21.  * Written by Matthew Kwan - December 1996
  22.  */
  23.  
  24. #include "snow.h"
  25.  
  26.  
  27. /*
  28.  * Declaration of global variables.
  29.  */
  30.  
  31. BOOL    compress_flag = FALSE;
  32. BOOL    quiet_flag = FALSE;
  33. int    line_length = 80;
  34.  
  35.  
  36. /*
  37.  * Encode a single character.
  38.  */
  39.  
  40. static BOOL
  41. character_encode (
  42.     unsigned char    c,
  43.     FILE        *infile,
  44.     FILE        *outfile
  45. ) {
  46.     int        i;
  47.  
  48.     for (i=0; i<8; i++) {
  49.         int        bit = ((c & (128 >> i)) != 0) ? 1 : 0;
  50.  
  51.         if (!compress_bit (bit, infile, outfile))
  52.         return (FALSE);
  53.     }
  54.  
  55.     return (TRUE);
  56. }
  57.  
  58.  
  59. /*
  60.  * Encode a string of characters.
  61.  */
  62.  
  63. static BOOL
  64. message_string_encode (
  65.     const char    *msg,
  66.     FILE        *infile,
  67.     FILE        *outfile
  68. ) {
  69.     compress_init ();
  70.  
  71.     while (*msg != '\0') {
  72.         if (!character_encode (*msg, infile, outfile))
  73.         return (FALSE);
  74.         msg++;
  75.     }
  76.  
  77.     return (compress_flush (infile, outfile));
  78. }
  79.  
  80.  
  81. /*
  82.  * Encode the contents of a file.
  83.  */
  84.  
  85. static BOOL
  86. message_fp_encode (
  87.     FILE        *msg_fp,
  88.     FILE        *infile,
  89.     FILE        *outfile
  90. ) {
  91.     int        c;
  92.  
  93.     compress_init ();
  94.  
  95.     while ((c = fgetc (msg_fp)) != EOF)
  96.         if (!character_encode (c, infile, outfile))
  97.         return (FALSE);
  98.  
  99.     if (ferror (msg_fp) != 0) {
  100.         perror ("Message file");
  101.         return (FALSE);
  102.     }
  103.  
  104.     return (compress_flush (infile, outfile));
  105. }
  106.  
  107.  
  108. /*
  109.  * Program's starting point.
  110.  * Processes command-line args and starts things running.
  111.  */
  112.  
  113. void
  114. main (
  115.     int        argc,
  116.     char        *argv[]
  117. ) {
  118.     int        c;
  119.     int        optind;
  120.     BOOL        errflag = FALSE;
  121.     BOOL        space_flag = FALSE;
  122.     char        *passwd = NULL;
  123.     char        *message_string = NULL;
  124.     FILE        *message_fp = NULL;
  125.     FILE        *infile = stdin;
  126.     FILE        *outfile = stdout;
  127.  
  128.     optind = 1;
  129.     for (optind = 1; optind < argc
  130. #ifdef unix
  131.             && argv[optind][0] == '-';
  132. #else
  133.             && (argv[optind][0] == '-' || argv[optind][0] == '/');
  134. #endif
  135.                         optind++) {
  136.         char    c = argv[optind][1];
  137.         char    *optarg;
  138.  
  139.         switch (c) {
  140.         case 'C':
  141.             compress_flag = TRUE;
  142.             break;
  143.         case 'Q':
  144.             quiet_flag = TRUE;
  145.             break;
  146.         case 'S':
  147.             space_flag = TRUE;
  148.             break;
  149.         case 'f':
  150.             if (argv[optind][2] != '\0')
  151.             optarg = &argv[optind][2];
  152.             else if (++optind == argc) {
  153.             errflag = TRUE;
  154.             break;
  155.             } else
  156.             optarg = argv[optind];
  157.  
  158.             if ((message_fp = fopen (optarg, "r")) == NULL) {
  159.             perror (optarg);
  160.             errflag = TRUE;
  161.             }
  162.             break;
  163.         case 'l':
  164.             if (argv[optind][2] != '\0')
  165.             optarg = &argv[optind][2];
  166.             else if (++optind == argc) {
  167.             errflag = TRUE;
  168.             break;
  169.             } else
  170.             optarg = argv[optind];
  171.  
  172.             if (sscanf (optarg, "%d", &line_length) != 1
  173.                             || line_length < 8) {
  174.             fprintf (stderr, "Illegal line length value '%s'\n",
  175.                                 optarg);
  176.             errflag = TRUE;
  177.             }
  178.             break;
  179.         case 'm':
  180.             if (argv[optind][2] != '\0')
  181.             optarg = &argv[optind][2];
  182.             else if (++optind == argc) {
  183.             errflag = TRUE;
  184.             break;
  185.             } else
  186.             optarg = argv[optind];
  187.  
  188.             message_string = optarg;
  189.             break;
  190.         case 'p':
  191.             if (argv[optind][2] != '\0')
  192.             optarg = &argv[optind][2];
  193.             else if (++optind == argc) {
  194.             errflag = TRUE;
  195.             break;
  196.             } else
  197.             optarg = argv[optind];
  198.  
  199.             passwd = optarg;
  200.             break;
  201.         default:
  202.             fprintf (stderr, "Illegal option '%s'\n", argv[optind]);
  203.             errflag = TRUE;
  204.             break;
  205.         }
  206.  
  207.         if (errflag)
  208.         break;
  209.     }
  210.  
  211.     if (message_string != NULL && message_fp != NULL) {
  212.         fprintf (stderr, "Cannot specify both message string and file\n");
  213.         errflag = TRUE;
  214.     }
  215.  
  216.     if (errflag || optind < argc - 2) {
  217.         fprintf (stderr, "Usage: %s [-C][-Q][-S]", argv[0]);
  218.         fprintf (stderr, "[-p passwd][-l line-len]");
  219.         fprintf (stderr, " [-f file | -m message]\n");
  220.         fprintf (stderr, "\t\t\t\t\t[infile [outfile]]\n");
  221.         exit (1);
  222.     }
  223.  
  224.     if (passwd != NULL)
  225.         password_set (passwd);
  226.  
  227.     if (optind < argc) {
  228.         if ((infile = fopen (argv[optind], "r")) == NULL) {
  229.         perror (argv[optind]);
  230.         exit (1);
  231.         }
  232.     }
  233.  
  234.     if (optind + 1 < argc) {
  235.         if ((outfile = fopen (argv[optind + 1], "w")) == NULL) {
  236.         perror (argv[optind + 1]);
  237.         exit (1);
  238.         }
  239.     }
  240.  
  241.     if (space_flag) {
  242.         space_calculate (infile);
  243.     } else if (message_string != NULL) {
  244.         if (!message_string_encode (message_string, infile, outfile))
  245.         exit (1);
  246.     } else if (message_fp != NULL) {
  247.         if (!message_fp_encode (message_fp, infile, outfile))
  248.         exit (1);
  249.         fclose (message_fp);
  250.     } else {
  251.         if (!message_extract (infile, outfile))
  252.         exit (1);
  253.     }
  254.  
  255.     if (outfile != stdout)
  256.         fclose (outfile);
  257.     if (infile != stdout)
  258.         fclose (infile);
  259.  
  260.     exit (0);
  261. }
  262.